package com.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.reggie.annotation.ApiHideController;
import com.reggie.common.R;
import com.reggie.common.ValidateCodeUtils;
import com.reggie.entity.user;
import com.reggie.service.userService;
import com.reggie.vo.loginVo;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import springfox.documentation.annotations.ApiIgnore;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
@Transactional
@RequestMapping("/user")
@Api(tags = {"用户登录控制器"})
public class userController {

    @Value("${spring.mail.username}")
    private String MailUserName;
    //注入javaMailSender对象
    @Autowired
    private JavaMailSender javaMailSender;
    //注入模板引擎，实现更复杂的邮件内容
    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private userService userService;

    //注入redisTemplate模板
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    /**
     * @param email
     * @return com.reggie.common.R<java.lang.String>
     * @description: 前端点击获取验证码，后端处理请求，向指定的邮箱发送邮件，采用redis缓存数据
     * @author 86187
     * @date: 2022/11/21 21:38
     */

    @GetMapping("/captcha")
    @ApiOperation(value = "用户邮箱注册", notes = "目前只支持邮箱注册")
    @ApiImplicitParams(
            value = {
                    @ApiImplicitParam(name = "email", value = "用户邮箱", paramType = "携带参数的类型", dataType = "String")
            }
    )
    public void SaveCreateUser(@RequestParam("email") @ApiParam(name = "用户邮箱", value = "用户注册时填写的合法邮箱") String email, HttpSession session) {
        //生成随机验证码
        String code = ValidateCodeUtils.generateValidateCode4String(6);
        //创建复杂邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            //创建复杂邮件对象的帮助类
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            //设置邮件主题
            mimeMessageHelper.setSubject("欢饮使用坤坤外卖，^_^!");
            //设置邮件的发件人
            mimeMessageHelper.setFrom(MailUserName);
            //设置收件人邮箱
            mimeMessageHelper.setTo(email);
            //设置邮件发送时间
            mimeMessageHelper.setSentDate(new Date());
            //设置上下文对象
            Context context = new Context();
            //在上下文对象设置验证码参数，让模板获取解析，展示到邮件内容中
            context.setVariable("code", code);
            String process = templateEngine.process("active-code.html", context);
            //设置邮件内容
            mimeMessageHelper.setText(process, true);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        //发送邮件
        javaMailSender.send(mimeMessage);
        //将验证码存放到redis中,并设置存活时间
        redisTemplate.opsForValue().set(email, code, 5, TimeUnit.MINUTES);
        log.info("{},{}的验证码为{}", LocalDateTime.now(), email, code);
    }

    /**
     * @param loginVo
     * @param session
     * @return com.reggie.common.R<java.lang.String>
     * @description: 从redis缓存中获取验证码实现登录和注册
     * @author 86187
     * @date: 2022/11/22 19:37
     */


    @PostMapping("/login")
    @ApiOperation(value = "用户邮箱登录", notes = "目前只支持邮箱登录")
    public R<String> toLoginByEmail(@RequestBody loginVo loginVo, HttpSession session) {
        String captcha = (String) redisTemplate.opsForValue().get(loginVo.getEmail());
        log.info("验证码为:{}", captcha);
        LambdaQueryWrapper<user> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(loginVo.getEmail() != null, user::getPhone, loginVo.getEmail());
        if (loginVo.getCode().equals(captcha)) {
            user ifExists = userService.getOne(userLambdaQueryWrapper);
            if (ifExists != null) {
                if (ifExists.getStatus() == 1) {
                    //将用户id存放进session域中
                    session.setAttribute("user", ifExists.getId());
                    //设置session的存活时间
                    session.setMaxInactiveInterval(60 * 60 * 24);
                    //清楚redis的key，释放缓存
                    redisTemplate.delete(loginVo.getEmail());
                    return R.success("登录成功!");
                }
            }
            //进行用户的注册
            user user = new user();
            user.setStatus(Integer.valueOf(1));
            user.setPhone(loginVo.getEmail());
            user.setSex("男");
            //用户名先随机生成
            user.setName(ValidateCodeUtils.generateValidateCode4String(8));
            boolean save = userService.save(user);
            if (save) {
                //将用户id存放进session域中
                session.setAttribute("user", user.getId());
                //设置session的存活时间
                session.setMaxInactiveInterval(60 * 60 * 24);
                redisTemplate.delete(loginVo.getEmail());
                return R.success("创建账户成功!");
            } else {
                return R.error("创建账户失败!请稍后再试!");
            }
        } else {
            return R.error("验证码错误，请确认你的验证码正确!");
        }
    }

    /**
     * @param session
     * @return com.reggie.common.R<java.lang.String>
     * @description: 实现用户的退出的功能
     * @author 86187
     * @date: 2022/11/24 17:38
     */

    @ApiHideController(value = "hide")
    @PostMapping("/loginout")
    @ApiIgnore
    @ApiOperation(value = "用户退出", notes = "用户进行安全退出,清空session")
    public R<String> loginOut(HttpSession session) {
        //清楚session，清除状态
        session.removeAttribute("user");
        return R.success("成功退出!");
    }

}
